broadway: Add broadway_node_equal
authorAlexander Larsson <alexl@redhat.com>
Wed, 29 Nov 2017 19:05:36 +0000 (20:05 +0100)
committerAlexander Larsson <alexl@redhat.com>
Thu, 30 Nov 2017 20:57:42 +0000 (21:57 +0100)
gdk/broadway/broadway-server.c
gdk/broadway/broadway-server.h
gdk/broadway/broadwayd.c

index 3cbd214d34b81430866011701c2901458a6396fc..bec36e3faed32486e854cfe56b0866a39f1dff5d 100644 (file)
@@ -145,6 +145,34 @@ broadway_node_free (BroadwayNode *node)
   g_free (node);
 }
 
+gboolean
+broadway_node_equal (BroadwayNode     *a,
+                    BroadwayNode     *b)
+{
+  int i;
+
+  if (a->hash != b->hash)
+    return FALSE;
+
+  if (a->type != b->type)
+    return FALSE;
+
+  if (a->n_data != b->n_data)
+    return FALSE;
+
+  if (a->n_children != b->n_children)
+    return FALSE;
+
+  for (i = 0; i < a->n_data; i++)
+    if (a->data[i] != b->data[i])
+      return FALSE;
+
+  for (i = 0; i < a->n_children; i++)
+    if (!broadway_node_equal (a->children[i], b->children[i]))
+      return FALSE;
+
+  return TRUE;
+}
 
 static void
 broadway_server_init (BroadwayServer *server)
index b24fc5ed042d8493c39411c4fa9d1eff97cb92d9..dba16288afcd463376ec1ab7a0b37b7e83df50dd 100644 (file)
@@ -22,12 +22,16 @@ typedef struct _BroadwayNode BroadwayNode;
 
 struct _BroadwayNode {
   guint32 type;
+  guint32 hash;
   guint32 n_children;
   BroadwayNode **children;
   guint32 n_data;
   guint32 data[1];
 };
 
+gboolean            broadway_node_equal                      (BroadwayNode     *a,
+                                                             BroadwayNode     *b);
+
 BroadwayServer     *broadway_server_new                      (char             *address,
                                                              int               port,
                                                               const char       *ssl_cert,
index 912a191ec746fdf85792d54b28d88c2e8b395ab3..a885a5e665f0be637cb5fbfb2652d2a88dfea73f 100644 (file)
@@ -224,6 +224,14 @@ get_client_serial (BroadwayClient *client, guint32 daemon_serial)
 #define NODE_SIZE_COLOR_STOP (NODE_SIZE_FLOAT + NODE_SIZE_COLOR)
 #define NODE_SIZE_SHADOW (NODE_SIZE_COLOR + 3 * NODE_SIZE_FLOAT)
 
+static guint32
+rotl (guint32 value, int shift)
+{
+  if ((shift &= 32 - 1) == 0)
+    return value;
+  return (value << shift) | (value >> (32 - shift));
+}
+
 static BroadwayNode *
 decode_nodes (BroadwayClient *client,
              int len, guint32 data[], int *pos)
@@ -233,6 +241,7 @@ decode_nodes (BroadwayClient *client,
   guint32 i, n_stops, n_shadows;
   guint32 size, n_children;
   gint32 texture_offset;
+  guint32 hash;
 
   g_assert (*pos < len);
 
@@ -304,6 +313,16 @@ decode_nodes (BroadwayClient *client,
   for (i = 0; i < n_children; i++)
     node->children[i] = decode_nodes (client, len, data, pos);
 
+  hash = node->type << 16;
+
+  for (i = 0; i < size; i++)
+    hash ^= rotl (node->data[i], i);
+
+  for (i = 0; i < n_children; i++)
+    hash ^= rotl (node->children[i]->hash, i);
+
+  node->hash = hash;
+
   return node;
 }